import 'package:badges/badges.dart';
import 'package:flutter/material.dart' hide Badge;
import 'package:mi_mang_flutter/model/public/menu_model.dart';
import 'package:mi_mang_flutter/res/dimens.dart';
import 'package:mi_mang_flutter/res/styles.dart';
import 'package:mi_mang_flutter/utils/image_utils.dart';

class GridMenu extends StatelessWidget {
  const GridMenu(
    this.items, {
    Key? key,
    this.headerWidget,
    this.crossAxisCount = 4,
    this.childAspectRatio = 1.28,
    this.imageFactor = 1.0 / 2.0,
    this.titleStyle,
    this.spacing,
    this.onTap,
    this.onTapItem,
    this.onTitleTap,
    this.itemPadding,
    this.badgePadding,
    this.badgePosition,
  }) : super(key: key);

  /// 头部标题
  final Widget? headerWidget;

  /// 菜单数组
  final List<MenuModel> items;

  /// 没行数目
  final int crossAxisCount;

  /// 宽高比例
  final double childAspectRatio;

  /// 图片所占比例(默认 3.0 / 4.0),
  ///
  /// 布局中存在上下结构的title,
  /// 图片尺寸超过0.6 , 3.0 / 5.0时,可能会引起文本内容溢出
  ///
  /// 注意: 设置比例时,使用double类型相除的方式设置
  final double imageFactor;

  /// 文字大小
  final TextStyle? titleStyle;

  /// 文字上下间距
  final double? spacing;

  /// item周边间距
  final EdgeInsets? itemPadding;

  /// 红点数值间距
  final EdgeInsets? badgePadding;

  /// 红点绝对位置
  final BadgePosition? badgePosition;

  /// onTap与onTapItem互斥
  final ValueChanged<int?>? onTap;
  final ValueChanged<MenuModel>? onTapItem;
  final GestureTapCallback? onTitleTap;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        headerWidget ?? Gaps.empty,
        GridView.builder(
          shrinkWrap: true,
          padding: itemPadding ?? EdgeInsets.zero,
          physics: NeverScrollableScrollPhysics(),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: crossAxisCount,
              childAspectRatio: childAspectRatio),
          itemCount: items.length,
          itemBuilder: (_, index) => _buildItem(index),
        ),
      ],
    );
  }

  Widget _buildItem(int index) {
    var item = items[index];
    return Material(
      color: Colors.transparent,
      child: Ink(
        child: InkWell(
          borderRadius: new BorderRadius.circular(Dimens.gapDp5),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Badge(
                badgeContent: Text('${item.badges}'),
                badgeStyle: BadgeStyle(
                  padding: badgePadding ??
                      EdgeInsets.symmetric(
                        horizontal: Dimens.gapDp8,
                        vertical: Dimens.gapDp1,
                      ),
                  shape: BadgeShape.square,
                  borderRadius:
                      BorderRadius.all(Radius.circular(Dimens.gapDp10)),
                  badgeColor: Color(0xFFd64769),
                  elevation: 0.0,
                ),
                showBadge: item.badges != 0,
                badgeAnimation: BadgeAnimation.fade(toAnimate: false),
                position: this.badgePosition ??
                    BadgePosition.topEnd(
                      top: -Dimens.gapDp1,
                      end: -Dimens.gapDp12,
                    ),
                child: FractionallySizedBox(
                  alignment: Alignment.topCenter,
                  widthFactor: this.imageFactor,
                  heightFactor: null,
                  child: item.isNetWorkImg!
                      ? loadNetworkImage(item.image)
                      : loadImage(item.image),
                ),
              ),
              SizedBox(height: spacing ?? Dimens.gapDp5),
              Text(
                item.title!,
                maxLines: 1,
                style: titleStyle ?? TextStyles.bodyLarge,
              )
            ],
          ),
          onTap: () {
            if (onTap != null) {
              onTap!(item.menuTag);
            } else if (onTapItem != null) {
              onTapItem!(item);
            }
          },
        ),
      ),
    );
  }
}
